package cn.com.coresystem.application.msg.mc;

import cn.com.yto56.coresystem.business.msg.mc.app.HttpMsgServerHandler;
import cn.com.yto56.coresystem.business.msg.mc.app.MsgServerHandler;
import cn.com.yto56.coresystem.common.msg.util.base.StringUtils;
import cn.com.yto56.coresystem.common.msg.util.io.AppConfigurationUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by wangrui on 2017/4/27.
 */
public class MsgManagerConnectionStarter {
    private static final Logger logger = LoggerFactory.getLogger(MsgManagerConnectionStarter.class);

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:spring/spring-*.xml");
        //获取服务端口
        String bindPort = AppConfigurationUtil.getPropertyValue("msg.mc.bindport");
        //spring管理
        try {

            if (StringUtils.isNotBlank(bindPort)) {
                logger.info("服务端开启等待客户端链接的，端口号[" + bindPort + "]");
                MsgManagerConnectionStarter msgManagerConnectionStarter = new MsgManagerConnectionStarter();
                msgManagerConnectionStarter.bind(Integer.parseInt(bindPort), applicationContext);
//                msgManagerConnectionStarter.bindHttp(8889, applicationContext);
            } else {
                logger.info("请填写正确的端口号，端口号为[" + bindPort + "]");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void bind(int port, final ApplicationContext applicationContext) {
        //boss 用来接收进来的连接
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //worker boss收到连接，会把连接信息注册到“worker”上
        EventLoopGroup workGroup = new NioEventLoopGroup();

        //启动NIO服务的辅助启动类
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        //注册通道
        serverBootstrap.group(bossGroup, workGroup);
        //频道类型
        serverBootstrap.channel(NioServerSocketChannel.class);
        //
        serverBootstrap.option(ChannelOption.SO_BACKLOG, 1024);
        //两个小时请求一次客户端
        serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);

        //channel
        serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                //字符串类解析
//                socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024));
                //设置解码为UTF-8
//                socketChannel.pipeline().addLast(new StringDecoder(Charset.forName("UTF-8")));
                //设置编码为UTF-8
//                socketChannel.pipeline().addLast(new StringEncoder(Charset.forName("UTF-8")));
                //添加心跳
//                socketChannel.pipeline().addLast("timeout", new IdleStateHandler(5, 5, 4, TimeUnit.SECONDS));
                // 在管道中添加我们自己的接收数据实现方法
                socketChannel.pipeline().addLast(new MsgServerHandler(applicationContext));
            }
        });

        //绑定端口
        ChannelFuture channelFuture = serverBootstrap.bind(port);

        try {
            //等待服务端监听端口关闭
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //退出
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }

    }


    public void bindHttp(int port, final ApplicationContext applicationContext) {
        //boss 用来接收进来的连接
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //worker boss收到连接，会把连接信息注册到“worker”上
        EventLoopGroup workGroup = new NioEventLoopGroup();

        //启动NIO服务的辅助启动类
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        //注册通道
        serverBootstrap.group(bossGroup, workGroup);
        //频道类型
        serverBootstrap.channel(NioServerSocketChannel.class);
        //
        serverBootstrap.option(ChannelOption.SO_BACKLOG, 1024);
        //两个小时请求一次客户端
        serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);

        //channel
        serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                socketChannel.pipeline().addLast("http-codec", new HttpServerCodec());
                socketChannel.pipeline().addLast("aggregator", new HttpObjectAggregator(65536));
                socketChannel.pipeline().addLast("http-chunked", new ChunkedWriteHandler());
                socketChannel.pipeline().addLast("handler", new HttpMsgServerHandler());
            }
        });

        //绑定端口
        ChannelFuture channelFuture = serverBootstrap.bind(port);

        try {
            //等待服务端监听端口关闭
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //退出
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }

    }

    public void bindWebSocket(int port, final ApplicationContext applicationContext) {
        //boss 用来接收进来的连接
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //worker boss收到连接，会把连接信息注册到“worker”上
        EventLoopGroup workGroup = new NioEventLoopGroup();

        //启动NIO服务的辅助启动类
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        //注册通道
        serverBootstrap.group(bossGroup, workGroup);
        //频道类型
        serverBootstrap.channel(NioServerSocketChannel.class);
        //
        serverBootstrap.option(ChannelOption.SO_BACKLOG, 1024);
        //两个小时请求一次客户端
        serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);

        //channel
        serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                socketChannel.pipeline().addLast("http-codec", new HttpServerCodec());
                socketChannel.pipeline().addLast("aggregator", new HttpObjectAggregator(65536));
                socketChannel.pipeline().addLast("http-chunked", new ChunkedWriteHandler());
                socketChannel.pipeline().addLast("handler", new HttpMsgServerHandler());
            }
        });

        //绑定端口
        ChannelFuture channelFuture = serverBootstrap.bind(port);

        try {
            //等待服务端监听端口关闭
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //退出
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }

    }
}
